package com.axend.lib_base.view.dialog

import android.app.Activity.RESULT_OK
import android.app.Dialog
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.util.Log
import android.view.View
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleObserver
import com.android.jws.JwsManager
import com.axend.lib_base.R
import com.axend.lib_base.bean.RadarUpBean
import com.axend.lib_base.databinding.BaseDialogCustomFirmwareUpgradeBinding
import com.axend.lib_base.engine.toast.toast
import com.axend.lib_base.ext.dp2px
import com.axend.lib_base.ext.expandTouchArea
import com.axend.lib_base.ext.roundToNearestInteger
import com.axend.lib_base.ext.runOnUIThread
import com.axend.lib_base.help.Constant.MMKV_KEY_RADAR_VERSION
import com.axend.lib_base.help.otgserial.SerialInter
import com.axend.lib_base.help.otgserial.SerialManage
import com.axend.lib_base.utils.ByteUtils
import com.axend.lib_base.utils.MMKVUtil
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException


/**
 * 固件升级弹窗
 */

class CustomFirmwareUpgradeDialog(activity: AppCompatActivity) : DialogFragment(), SerialInter,
    LifecycleObserver {


    private lateinit var dialogBinding: BaseDialogCustomFirmwareUpgradeBinding
    private var showModel = 0//0:默认radar固件版本，1：选择固件.bin，2：更新进度界面
    private var filePath: String? = null//文件路径
    private var upRadarFlag = false//是否为radar固件升级,默认为false
    var fileBuffer: ByteArray = ByteArray(0)
    var activity: AppCompatActivity = activity

    private lateinit var filePickerLauncher: ActivityResultLauncher<Intent>

    companion object {
        const val REQUEST_CODE_FILE_PICKER = 100
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // 创建自定义Dialog
        val inflater = requireActivity().layoutInflater
        dialogBinding = DataBindingUtil.inflate(
            inflater,
            R.layout.base_dialog_custom_firmware_upgrade,
            null,
            false
        )
        /*初始化*/
        showModel(0)


        SerialManage.getInstance().init(this, true)
        SerialManage.getInstance().open(true)
        val port = 1
        val jwsManager = JwsManager.create(requireContext())
        jwsManager.jwsSetExtrnalGpioValue(port, true)

        dialogBinding.tvRadarVersion.text=MMKVUtil.instance.decode(MMKV_KEY_RADAR_VERSION,"v0.1");
        dialogBinding.ivClose.expandTouchArea(50)
        dialogBinding.tvUpdate.expandTouchArea(50)

        dialogBinding.tvUpdate.setOnClickListener {
            showModel(1)
        }

        dialogBinding.btUpdate.setOnClickListener {
            if (filePath.isNullOrEmpty()) {
                toast(context?.getString(R.string.app_tips_select_file))
                return@setOnClickListener
            }

            var file = File(filePath)
            if (!file.name.endsWith(".bin")) {
                toast(context?.getString(R.string.app_tips_select_file_end_bin))
                return@setOnClickListener
            }

            try {
                val fileInputStream = FileInputStream(file)
                fileBuffer = ByteArray(fileInputStream.available())
                fileInputStream.read(fileBuffer)
                fileInputStream.close()
            } catch (e: FileNotFoundException) {
                throw RuntimeException(e)
            } catch (e: IOException) {
                throw RuntimeException(e)
            }
            upRadarFlag=true
            showModel(2)
        }

        /*文件选择器*/
        dialogBinding.llFileSelect.setOnClickListener {
            showFileChooser()
        }

        /*关闭*/
        dialogBinding.ivClose.setOnClickListener {
            SerialManage.getInstance().colse()
            dismiss()
        }

        /*取消按钮*/
        dialogBinding.btCancel.setOnClickListener {
            SerialManage.getInstance().colse()
            dismiss()
        }
        setupFilePicker()
        return Dialog(requireContext(), R.style.Common_CustomDialog).apply {
            setContentView(dialogBinding.root)
            setCanceledOnTouchOutside(false)
            val window = window
            window?.apply {
                val layoutParams = window.attributes
                layoutParams.dimAmount = 0.5f // 设置透明度
                layoutParams.width = dp2px(540f)
                window.attributes = layoutParams
                clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
            }
        }
    }

    override fun show(manager: FragmentManager, tag: String?) {
        if (this.isVisible) dismiss()
        super.show(manager, tag)
    }


    /**
     * 设置显示模式
     */
    private fun showModel(model: Int) {
        when (model) {
            0 -> {
                dialogBinding.clRadarVersionContent.visibility = View.VISIBLE
                dialogBinding.clSelectFileContent.visibility = View.GONE
                dialogBinding.llProgress.visibility = View.GONE
            }

            1 -> {
                dialogBinding.clRadarVersionContent.visibility = View.GONE
                dialogBinding.clSelectFileContent.visibility = View.VISIBLE
                dialogBinding.llProgress.visibility = View.GONE
            }

            2 -> {
                dialogBinding.clRadarVersionContent.visibility = View.GONE
                dialogBinding.clSelectFileContent.visibility = View.GONE
                dialogBinding.llProgress.visibility = View.VISIBLE
            }
        }
    }

    private fun showFileChooser() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.type = "application/octet-stream" // 设置为所有文件类型
        intent.addCategory(Intent.CATEGORY_OPENABLE)

        // 设置文件类型过滤器，这里我们只允许.bin文件
        intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/octet-stream"))

        // 启动文件选择器
        filePickerLauncher.launch(intent)
    }


    private fun setupFilePicker() {
        filePickerLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result ->
            if (result.resultCode == RESULT_OK) {
                val data: Intent? = result.data
                data?.data?.also { uri ->
                    Log.d("FileSelected", "Selected file path: $uri")
                    val filePath = getAbsolutePathFromUri(requireContext(), uri)
                    Log.d("FileSelected", "Selected file path: $filePath")
                    dialogBinding.tvFilePath.text = filePath
                    this.filePath = filePath
                }
            }
        }
    }

    private fun getAbsolutePathFromUri(context: Context, uri: Uri): String? {
        if (DocumentsContract.isDocumentUri(context, uri)) {
            val docId = DocumentsContract.getDocumentId(uri)
            // 外部存储文档
            if ("com.android.externalstorage.documents" == uri.authority) {
                val idParts = docId.split(":").toTypedArray()
                if (idParts.size == 2 && idParts[0] == "primary") {
                    return "${Environment.getExternalStorageDirectory()}/${idParts[1]}"
                }else if (idParts.size == 2 && idParts[0] != "primary") {
                    // 假设 U 盘挂载路径为 /storage/usb0
                    return "/storage/${idParts[0]}/${idParts[1]}"
                }
            } else if (uri.authority == "com.android.providers.downloads.documents") {
                val id = docId.replaceFirst("^\\d+$".toRegex(), "")
                val contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"),
                    id.toLong()
                )
                return getDataColumn(context, contentUri, null, null)
            }
        } else if ("content" == uri.scheme) {
            return getDataColumn(context, uri, null, null)
        } else if ("file" == uri.scheme) {
            return uri.path
        }
        return null
    }

    private fun getDataColumn(
        context: Context,
        uri: Uri?,
        selection: String?,
        selectionArgs: Array<String>?
    ): String? {
        var cursor: Cursor? = null
        val column = "_data"
        val projection = arrayOf(column)
        try {
            cursor =
                context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
            if (cursor != null && cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndexOrThrow(column)
                return cursor.getString(columnIndex)
            }
        } finally {
            cursor?.close()
        }
        return null
    }

    override fun connectMsg(path: String?, isSucc: Boolean) {

    }

    override fun readData(path: String?, bytes: ByteArray?, size: Int) {

    }

    /*文件升级*/
    override fun writeData(): RadarUpBean {
        val file: ByteArray = fileBuffer
        val bean = RadarUpBean(file, upRadarFlag)
        upRadarFlag = false
        return bean
    }

    override fun radarVersion(bytes: ByteArray?) {
        val result: String = ByteUtils.byteArrayToCommaSeparatedString(bytes!!)
        Log.d("RadarVersion0", result)
        val Version = "V$result"
        Log.d("RadarVersion1", Version)
        /*存储版本号*/
        MMKVUtil.instance.encode(MMKV_KEY_RADAR_VERSION,Version)
        runOnUIThread {
            dialogBinding.tvRadarVersion.text = Version
        }
    }

    override fun updata_button_click(): Boolean {
        return upRadarFlag
    }

    override fun progress(progress: Int, total: Int) {
       runOnUIThread {
           dialogBinding.progressbar.max = total
           dialogBinding.progressbar.progress = progress
           /*计算百分比*/
           val percentage = (progress.toFloat() / total.toFloat()) * 100
           Log.d("progress", "percentage:$percentage")
           dialogBinding.tvProgress.text = getString(
               R.string.app_dialog_update_firmware_percent,
               "${percentage.roundToNearestInteger()}%"
           )
           if (progress == total) {
               SerialManage.getInstance().colse()
               dismiss()
               toast(R.string.app_tips_success)
           }
       }
    }

    override fun onDestroy() {
        super.onDestroy()
        SerialManage.getInstance().colse()
    }
}